package com.etone.smartAudit.service;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etone.smartAudit.domain.Quota;
import com.etone.smartAudit.dto.AccountAuditDTO;
import com.etone.smartAudit.error.CustomParameterizedException;
import com.etone.smartAudit.mapper.QuotaMapper;
import com.etone.smartAudit.onlyoffice.util.QuotaDataListener;
import com.etone.smartAudit.utils.StringUtil;
import com.etone.smartAudit.vo.jiutian.CommonVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static javax.print.attribute.ResolutionSyntax.DPI;


/**
 * @author: 张任豪
 * @create: 2021-11-25 16:55:15
 * @Description 定额库
 */
@Service
@AllArgsConstructor
@Slf4j
public class QuotaService {

    private QuotaMapper quotaMapper;

    /**
     * 导入定额库
     * @param file
     * @return
     */
    public CommonVO importQuota(MultipartFile file){
        try {
            EasyExcel.read(file.getInputStream(), Quota.class,new QuotaDataListener(quotaMapper)).headRowNumber(1).sheet("定额库").doRead();
        } catch (Exception e) {
            return new CommonVO("500",e.getMessage(),null);
        }
        return new CommonVO("200","导入成功!",null);
    }

    public CommonVO accountAudit(MultipartFile file, HttpServletResponse response){
        List<AccountAuditDTO> list = null;
        try {
            list = EasyExcel.read(file.getInputStream()).head(AccountAuditDTO.class).sheet("表3甲").headRowNumber(5).doReadSync();
            List<AccountAuditDTO> auditList = autoAudit(list);

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("审核结果" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), AccountAuditDTO.class).sheet("表3甲").doWrite(auditList);
            return new CommonVO("200","审核成功",null);
        } catch (Exception e) {
            log.info("审核失败：{}",e.getMessage());
            return new CommonVO("500",e.getMessage(),null);
        }
    }



    /**
     * 存储定额库数据
     * @param cachedDataList
     */
    public void saveData(List<Quota> cachedDataList) {
        quotaMapper.saveAll(cachedDataList);
    }

    /**
     * 审核结算单数据并进行处理
     * @param list
     * @return
     */
    public List<AccountAuditDTO> autoAudit(List<AccountAuditDTO> list) {

        for (AccountAuditDTO accountAuditDTO : list) {
            //通过定额编号从数据库中找到对应的定额编号
            if (!StringUtils.isEmpty(accountAuditDTO.getQuotaCode())){
                QueryWrapper<Quota> wrapper = new QueryWrapper<>();
                wrapper.eq("quota_code",accountAuditDTO.getQuotaCode());
                Quota quota = quotaMapper.selectOne(wrapper);
                //开始校验
                if (quota!=null){
                    //校验技工定额
                    if (!StringUtils.isEmpty(accountAuditDTO.getArtisanPrice())){
                        BigDecimal b1 = new BigDecimal(accountAuditDTO.getArtisanPrice());
                        if (b1.compareTo(quota.getArtisanPrice()) != 0){
                            accountAuditDTO.setMessage("技工单位定额值不一致");
                            continue;
                        }
                        if (!StringUtils.isEmpty(accountAuditDTO.getNumber())){
                            BigDecimal num = new BigDecimal(accountAuditDTO.getNumber());
                            //技术总额
                            BigDecimal b1All = b1.multiply(num).setScale(2,BigDecimal.ROUND_HALF_UP);
                            BigDecimal b1All2 = new BigDecimal(accountAuditDTO.getArtisanAll());
                            if (b1All.compareTo(b1All2) != 0){
                                accountAuditDTO.setMessage("技工单位总合计不正确");
                                continue;
                            }
                        }
                    }
                    //校验普工定额
                    if (!StringUtils.isEmpty(accountAuditDTO.getGeneralPrice())){
                        BigDecimal g1 = new BigDecimal(accountAuditDTO.getGeneralPrice());
                        if (g1.compareTo(quota.getGeneralPrice()) != 0){
                            accountAuditDTO.setMessage("普工单位定额不一致");
                            continue;
                        }
                        if (!StringUtils.isEmpty(accountAuditDTO.getNumber())){
                            BigDecimal num = new BigDecimal(accountAuditDTO.getNumber());
                            //技术总额
                            BigDecimal g1All = g1.multiply(num).setScale(2,BigDecimal.ROUND_HALF_UP);
                            BigDecimal g1All2 = new BigDecimal(accountAuditDTO.getGeneralPrice());
                            if (g1All.compareTo(g1All2) != 0){
                                accountAuditDTO.setMessage("普工单位总合计不正确");
                                continue;
                            }
                        }
                    }
                    accountAuditDTO.setMessage("通过");
                }else {
                    accountAuditDTO.setMessage("在定额库中没有匹配的定额编码");
                }
            }
        }
        return list;
    }

    public void pdfConvertToImg(MultipartFile file, HttpServletResponse response) {

        List<byte[]> result = new ArrayList<>();
        ZipOutputStream zos = null;
        try {
            PDDocument document = PDDocument.load(file.getInputStream());
            PDFRenderer renderer = new PDFRenderer(document);
            for (int i = 0; i < document.getNumberOfPages(); ++i) {
                BufferedImage bufferedImage = renderer.renderImageWithDPI(i, DPI);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "png", out);
                result.add(out.toByteArray());
            }
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename="+file.getName()+".zip");
            zos = new ZipOutputStream(response.getOutputStream());
            for (int i = 0; i < result.size(); i++) {
                ZipEntry zipEntry = new ZipEntry(i + ".png");
                zos.putNextEntry(zipEntry);
                zos.write(result.get(i));
            }

        } catch (Exception e) {
            log.info("pdf转换异常:{}", e.getMessage());
            throw new CustomParameterizedException(e.getMessage());
        } finally {
            try {
                zos.finish();
                zos.close();
            } catch (Exception e) {
                log.info("流关闭异常:{}", e.getMessage());
            }
        }
    }
}
